//
//  RaeNetworkProtocol.swift
//  77Club
//
//  Created by Apple on 2024/8/26.
//

import Foundation
import KakaJSON
import Alamofire
import AdSupport

extension RaeNetworkWrapper {
    
    func request<Model: Convertible>(_ config: RaeRequestApi, type: Model.Type) async -> RaeNetworkResult<Model> {
        let result = await request(config)
        if result.isSuccess, let infos = result.models {
            let models = infos.kj.modelArray(type.self)
            return .success(models)
        } else {
            return .failure(.error(code: result.errorCode ?? 0, error: result.errorMessage ?? ""))
        }
    }
    
    func request(_ config: RaeRequestApi, isShowError: Bool = true) async -> RaeNetworkResult<[String: Any]> {
        let request = AF.request(config.request)
        return await withCheckedContinuation({ continuation in
            request.responseString { response in
                DispatchQueue.main.async {
                    switch response.result {
                    case .success(let value):
                        continuation.resume(returning: analysisNetworkSuccess(config, infoData: value))
                        return
                    case .failure(let error):
                        continuation.resume(returning: analysisNetworkError(config, error: error))
                        return
                    }
                }
            }
        })
    }
    
    //TODO: - 解析网络成功数据返回
    private func analysisNetworkSuccess(_ config: RaeRequestApi, infoData: Any?) -> RaeNetworkResult<[String: Any]> {
        var resultModel: RaeNetworkBaseModel?
        if let data = infoData as? Data {
            resultModel = data.kj.model(RaeNetworkBaseModel.self)
        } else if let infoStr = infoData as? String {
            resultModel = infoStr.kj.model(RaeNetworkBaseModel.self)
        }
        guard let resultModel else {
            GlobalTool.shared.showToast(message: "数据解析失败！")
            return .failure(.error(code: 51001, error: "数据解析失败！"))
        }
        
        if resultModel.code == 500 {
            GlobalTool.shared.showToast(message: resultModel.msg)
            return .failure(.error(code: 51001, error: resultModel.msg))
        }
        
        if let data = resultModel.data as? [String: Any] {
            return .success([data])
        }
        
        if let data = resultModel.data as? [[String: Any]] {
            return .success(data)
        }
        
        if let data = resultModel.data as? String {
            return .success([["value": data]])
        }
               
        return .success([])
    }
    
    //TODO: - 解析网络错误返回
    private func analysisNetworkError<T>(_ config: RaeRequestApi, error: AFError) -> RaeNetworkResult<T> {
        if let underlyingError = error.underlyingError, let urlError = underlyingError as? URLError {
            let errorDesc = urlError.localizedDescription
            if urlError.code == .timedOut {
                AF.cancelAllRequests()
            }
            let statusCode = urlError.code.rawValue
            return .failure(.error(code: statusCode, error: errorDesc))
        } else {
            return .failure(.error(code: error.responseCode ?? 0, error: error.localizedDescription))
        }
    }
    
    //MARK: ==============================================================
    func requestSpecialData<Model: Convertible>(_ config: RaeRequestApi, type: Model.Type, isShowError: Bool = true) async -> RaeNetworkResult<Model>  {
        let result = await requestSpecial(config)
        if result.isSuccess, let infos = result.models {
            let models = infos.kj.modelArray(type.self)
            return .success(models)
        } else {
            return .failure(.error(code: result.errorCode ?? 0, error: result.errorMessage ?? ""))
        }
    }
    
    func requestSpecial(_ config: RaeRequestApi, _ postType: HTTPMethod = .get) async -> RaeNetworkResult<[String: Any]> {

        var header:HTTPHeaders =
        ["Content-Type":"application/x-www-form-urlencoded",
        ]
        if let token = UserDefaultsManager.getString(forKey: .token) {
            header["token"] = token
        }
        var urlString = RaeRequestParameterConfig.shared.baseUrlStr
        urlString = urlString + config.path
        
        var requestType: HTTPMethod = .get
        if config.isPostRequest {
            requestType = .post
        }
//        postType = ispos
        print("=========urlString\(urlString)")
        
        let request = AF.request(URL(string: urlString)!, method: requestType, parameters: config.parameters, headers: header)
        return await withCheckedContinuation({ continuation in
            request.responseString { response in
                DispatchQueue.main.async {
                    switch response.result {
                    case .success(let value):
                        continuation.resume(returning: analysisNetworkSuccess(config, infoData: value))
                        return
                    case .failure(let error):
                        continuation.resume(returning: analysisNetworkError(config, error: error))
                        return
                    }
                }
            }
        })
    }
}
